local CATEGORY_NAME = "Self commands"

local syssetreason = false
function ulx.kickme( calling_ply, reason )
	local syssetreason = false
	if reason == "" then
		reason = "You wanted to!"
		syssetreason = true
	end
	ULib.kick( calling_ply, reason )
	if reason and reason ~= "" and not syssetreason then
		return true, "#1s kicked him/herself (#3s) ... xD xD xD xD"
	end
	
	return true
end
local kickme = ulx.command( CATEGORY_NAME, "ulx kickme", ulx.kickme, "!kickme" )
kickme:addParam{ type=ULib.cmds.StringArg, hint="reason", ULib.cmds.optional, ULib.cmds.takeRestOfLine }
kickme:defaultAccess( ULib.ACCESS_ALL )
kickme:help( "kicks yourself." )
kickme:logString( "#1s kicked him/herself" )

function ulx.whipme( calling_ply, times, dmg )
	local i = 1
	if calling_ply.whipped then
		ULib.tsayError( calling_ply, v:Nick() .. " is already being whipped by " .. calling_ply.whippedby, true )
		table.remove( target_plys, i )
	else
		local dtime = 0
		calling_ply.whipped = true
		calling_ply.whippedby = calling_ply:IsValid() and calling_ply:Nick() or "(Console)"
		calling_ply.whipcount = 0
		calling_ply.whipamt = times
		timer.Create( "ulxWhip" .. v:EntIndex(), 0.5, 0, function()
			if not v:IsValid() then return end
			if calling_ply.whipcount == calling_ply.whipamt or not v:Alive() then
				calling_ply.whipped = nil
				calling_ply.whippedby = nil
				calling_ply.whipcount = nil
				calling_ply.whipamt = nil
				timer.Remove( "ulxWhip" .. v:EntIndex() )
			else
				ULib.slap( v, dmg )
				calling_ply.whipcount = calling_ply.whipcount + 1
			end
		end )
	end

	return true
end
local whipme = ulx.command( CATEGORY_NAME, "ulx whipme", ulx.whipme, "!whipme" )
whipme:addParam{ type=ULib.cmds.NumArg, min=2, max=20, default=10, hint="times", ULib.cmds.optional, ULib.cmds.round }
whipme:addParam{ type=ULib.cmds.NumArg, min=0, default=0, hint="damage", ULib.cmds.optional, ULib.cmds.round }
whipme:defaultAccess( ULib.ACCESS_ALL )
whipme:help( "whips yourself x times with given damage each time." )
whipme:logString( "#1s is whipping him/herself #3i times with #4i damage" )

function ulx.godme( calling_ply, should_revoke )
	if not calling_ply:IsValid() then
		if not should_revoke then
			Msg( "You are the console, you are already god.\n" )
		else
			Msg( "Your position of god is irrevocable; if you don't like it, leave the matrix.\n" )
		end
		return
	end
	if ulx.getExclusive( calling_ply, calling_ply ) then
		ULib.tsayError( calling_ply, ulx.getExclusive( calling_ply, calling_ply ), true )
		return false
	else
		if not should_revoke then
			calling_ply:godEnable()
			calling_ply.ULXHasgodme = true
		else
			calling_ply:godDisable()
			calling_ply.ULXHasgodme = nil
		end
	end
	return true
end
local godme = ulx.command( CATEGORY_NAME, "ulx godme", ulx.godme, "!godme" )
godme:addParam{ type=ULib.cmds.BoolArg, invisible=true }
godme:defaultAccess( ULib.ACCESS_ALL )
godme:help( "Grants god mode to yourself." )
godme:logString( "#1s granted godme mode to him/herself" )
godme:setOpposite( "ulx ungodme", {_, _, true}, "!ungodme" )
godme:oppositeLogString( "#1s revoked god mode from him/herself" )

function ulx.hpme( calling_ply, amount )
	calling_ply:SetHealth( amount )
	return true
end
local hpme = ulx.command( CATEGORY_NAME, "ulx hpme", ulx.hpme, "!hpme" )
hpme:addParam{ type=ULib.cmds.NumArg, min=1, max=55555, hint="hp", ULib.cmds.round }
hpme:defaultAccess( ULib.ACCESS_ALL )
hpme:help( "Sets your hp." )
hpme:logString( "#1s set his/her hp to #3i" )

function ulx.armorme( calling_ply, amount )
	calling_ply:SetArmor( amount )
	return true
end
local armorme = ulx.command( CATEGORY_NAME, "ulx armorme", ulx.armorme, "!armorme" )
armorme:addParam{ type=ULib.cmds.NumArg, min=0, max=55555, hint="armor", ULib.cmds.round }
armorme:defaultAccess( ULib.ACCESS_ALL )
armorme:help( "Sets the armor for target(s)." )
armorme:logString( "#1s set his/her armor to #2i" )

function ulx.ragdollme( calling_ply, should_unragdoll )	
	local i = 1
	local v = calling_ply
	if not should_unragdoll then
		if ulx.getExclusive( v, calling_ply ) then
			ULib.tsayError( calling_ply, ulx.getExclusive( v, calling_ply ), true )
			table.remove( target_plys, i )
		else			
			if v:InVehicle() then
				local vehicle = v:GetParent()
				v:ExitVehicle()
			end
		
			ULib.getSpawnInfo( v )
		
			local ragdoll = ents.Create( "prop_ragdoll" )
			ragdoll.ragdolledPly = v
			ragdoll:SetPos( v:GetPos() )
			local velocity = v:GetVelocity()
			ragdoll:SetAngles( v:GetAngles() )
			ragdoll:SetModel( v:GetModel() )
			ragdoll:Spawn()
			ragdoll:Activate()
			v:SetParent( ragdoll )
			for i=1, 14 do
				ragdoll:GetPhysicsObjectNum( i ):SetVelocity( velocity )
			end
			v:Spectate( OBS_MODE_CHASE )
			v:SpectateEntity( ragdoll )
			v:StripWeapons()
			ragdoll:DisallowDeleting( true, function( old, new )
				v.ragdoll = new
			end )
			v:DisallowSpawning( true )
			v.ragdoll = ragdoll
			ulx.setExclusive( v, "ragdolled" )
		end
	else
		if v.ragdoll then -- Only if they're ragdolled...
			v:DisallowSpawning( false )
			v:SetParent()
			v:UnSpectate() -- Need this for DarkRP for some reason, works fine without it in sbox
			local ragdoll = v.ragdoll
			v.ragdoll = nil -- Gotta do this before spawn or our hook catches it
			if not ragdoll:IsValid() then -- Something must have removed it, just spawn
				ULib.spawn( v, true )
			else
				local pos = ragdoll:GetPos()
				pos.z = pos.z + 10 -- So they don't end up in the ground
				ULib.spawn( v, true )
				v:SetPos( pos )
				v:SetVelocity( ragdoll:GetVelocity() )
				local yaw = ragdoll:GetAngles().yaw
				v:SetAngles( Angle( 0, yaw, 0 ) )
				ragdoll:DisallowDeleting( false )
				ragdoll:Remove()
			end
			ulx.clearExclusive( v )
		else
			return
		end
	end
	return true
end
local ragdollme = ulx.command( CATEGORY_NAME, "ulx ragdollme", ulx.ragdollme, "!ragdollme" )
ragdollme:addParam{ type=ULib.cmds.BoolArg, invisible=true }
ragdollme:defaultAccess( ULib.ACCESS_ALL )
ragdollme:help( "ragdolls yourself." )
ragdollme:logString( "#1s ragdolled him/herself" )
ragdollme:setOpposite( "ulx unragdollme", {_, _, true}, "!unragdollme" )
ragdollme:oppositeLogString( "#1s unragdolled him/herself" )

function ulx.teleportme( calling_ply )
	if not calling_ply:IsValid() then
		Msg( "You are the console, you can't teleport since you can't see the world!\n" )
		return
	end

	if ulx.getExclusive( calling_ply, calling_ply ) then
		ULib.tsayError( calling_ply, ulx.getExclusive( calling_ply, calling_ply ), true )
		return
	end

	if not calling_ply:Alive() then
		ULib.tsayError( calling_ply, calling_ply:Nick() .. " is dead!", true )
		return
	end

	local t = {}
	t.start = calling_ply:GetPos() + Vector( 0, 0, 32 ) -- Move them up a bit so they can travel across the ground
	t.endpos = calling_ply:GetPos() + calling_ply:EyeAngles():Forward() * 16384
	t.filter = calling_ply
	if calling_ply ~= calling_ply then
		t.filter = { calling_ply, calling_ply }
	end
	local tr = util.TraceEntity( t, calling_ply )

	local pos = tr.HitPos

	if calling_ply == calling_ply and pos:Distance( calling_ply:GetPos() ) < 64 then -- Laughable distance
		return
	end

	if calling_ply:InVehicle() then
		calling_ply:ExitVehicle()
	end

	calling_ply:SetPos( pos )
	calling_ply:SetLocalVelocity( Vector( 0, 0, 0 ) ) -- Stop!

	if calling_ply ~= calling_ply then
		return true
	end
end
local teleportme = ulx.command( CATEGORY_NAME, "ulx teleportme", ulx.teleportme, "!teleportme" )
teleportme:defaultAccess( ULib.ACCESS_ALL )
teleportme:help( "teleports yourself." )
teleportme:logString( "#1s teleported him/herself" )